using System;
using System.Collections.Generic;
using System.Linq;

/*This Class Originally wrote By Rob Conery from Microsoft and I update several things like Page index always start by 1 not 0 */
/* Eko Santoso */

namespace Infrastucture
{
    public interface IPagedList
    {
        int TotalCount { get; set; }

        int PageCount { get; set; }

        int PageIndex { get; set; }

        int PageSize { get; set; }

        bool IsPreviousPage { get; }

        bool IsNextPage { get; }
    }

    public class PagedList<T> : List<T>, IPagedList
    {
        public PagedList(IQueryable<T> source, int index, int pageSize)
        {
            TotalCount = source.Count();
            PageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDecimal(TotalCount)/Convert.ToDecimal(pageSize)));
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip((index - 1)*pageSize).Take(pageSize).ToList());
        }

        public PagedList(List<T> source, int index, int pageSize)
        {
            TotalCount = source.Count();
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip((index - 1)*pageSize).Take(pageSize).ToList());
        }

        public PagedList(IList<T> source, int index, int pageSize)
        {
            TotalCount = source.Count();
            PageCount = TotalCount/pageSize;
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip((index - 1)*pageSize).Take(pageSize).ToList());
        }

        public PagedList(IEnumerable<T> source, int index, int pageSize)
        {
            TotalCount = source.Count();
            PageCount = TotalCount/pageSize;
            PageSize = pageSize;
            PageIndex = index;
            AddRange(source.Skip((index - 1)*pageSize).Take(pageSize).ToList());
        }

        #region IPagedList Members

        public int TotalCount { get; set; }

        public int PageCount { get; set; }

        public int PageIndex { get; set; }

        public int PageSize { get; set; }

        public bool IsPreviousPage
        {
            get { return (PageIndex > 1); }
        }

        public bool IsNextPage
        {
            get { return ((PageIndex)*PageSize) < TotalCount; }
        }

        #endregion
    }

    public static class Pagination
    {
        public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index, int pageSize)
        {
            return new PagedList<T>(source, index, pageSize);
        }

        public static PagedList<T> ToPagedList<T>(this IQueryable<T> source, int index)
        {
            return new PagedList<T>(source, index, 30);
        }

        public static PagedList<T> ToPagedList<T>(this List<T> source, int index, int pageSize)
        {
            return new PagedList<T>(source, index, pageSize);
        }

        public static PagedList<T> ToPagedList<T>(this List<T> source, int index)
        {
            return new PagedList<T>(source, index, 10);
        }


        public static PagedList<T> ToPagedList<T>(this IList<T> source, int index, int pagesize)
        {
            return new PagedList<T>(source, index, pagesize);
        }

        public static PagedList<T> ToPagedList<T>(this IEnumerable<T> source, int index)
        {
            return new PagedList<T>(source, index, 20);
        }
    }
}